#include "glsprites.h"
#include <QKeyEvent>
#include <QBitmap>
#include "math.h"
#include <QMessageBox>

GLWidget::GLWidget() : QGLWidget()
{
    mouseLocked = false;

    gameState = 0;
    stateSelection[0] = 0;
    stateSelection[1] = 4;
    gameType = 0;
    gamePlayers = 0;

    font = QFont("Verdana", 20, 0, 0 );

    // pagrindinis meniu
    txt[0].append( TMLabel(QString::fromStdWString(L"Biliardas"), 300, 50, font, -1 ) );
    myg[0].append( TMLabel(QString::fromStdWString(L"Naujas žaidimas"), 300, 100, font, 0 ) );
    myg[0].append( TMLabel(QString::fromStdWString(L"Tęsti žaidimą"), 300, 150, font, 1) );
    myg[0].append( TMLabel(QString::fromStdWString(L"Nustatymai"), 300, 200, font, 2) );
    myg[0].append( TMLabel(QString::fromStdWString(L"Baigti"), 300, 250, font, 3) );

    // Naujas žaidimas
    gameTypeStrings[0] = QString::fromStdWString(L"Pulas 8");
    gameTypeStrings[1] = QString::fromStdWString(L"Pulas 9");

    gamePlayersStrings[0] = QString::fromStdWString(L"1P vs 2P");
    gamePlayersStrings[1] = QString::fromStdWString(L"1P vs AI");

    txt[1].append( TMLabel(QString::fromStdWString(L"Naujas žaidimas"), 300, 50, font, -1));
    txt[1].append( TMLabel(QString::fromStdWString(L"Žaidimo tipas:"), 300, 100, font, -1));
    txt[1].append( TMLabel(QString::fromStdWString(L"Žaidėjai:"), 300, 150, font, -1));
    myg[1].append( TMLabel(QString::fromStdWString(L"<"), txt[1][1].x2+10, 100, font, 0));
    myg[1].append( TMLabel(QString::fromStdWString(L">"), txt[1][1].x2+200, 100, font, 1));
    myg[1].append( TMLabel(QString::fromStdWString(L"<"), txt[1][2].x2+10, 150, font, 2));
    myg[1].append( TMLabel(QString::fromStdWString(L">"), txt[1][2].x2+200, 150, font, 3));
    myg[1].append( TMLabel(QString::fromStdWString(L"Žaisti"), 300, 200, font, 4));
    myg[1].append( TMLabel(QString::fromStdWString(L"Grįžti"), 300, 250, font, 5));

    // žaidimo pauzė
    txt[2].append( TMLabel(QString::fromStdWString(L"Pauzė"), 300, 100, font, -1));
    myg[2].append( TMLabel(QString::fromStdWString(L"Nustatymai"), 300, 200, font, 0));
    myg[2].append( TMLabel(QString::fromStdWString(L"Išsaugoti žaidimą"), 300, 250, font, 1));
    myg[2].append( TMLabel(QString::fromStdWString(L"Pagabla"), 300, 300, font, 2));
    myg[2].append( TMLabel(QString::fromStdWString(L"Baigti žaidimą"), 300, 350, font, 3));
    myg[2].append( TMLabel(QString::fromStdWString(L"Grįžti į žaidimą"), 300, 400, font, 4));





}

GLWidget::~GLWidget()
{
}

// GL inicijavimo metodas
void GLWidget::initializeGL()
{    
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    texture[0] = bindTexture(QPixmap(QString(":/img/MAX0010.jpg")), GL_TEXTURE_2D);
    texture[1] = bindTexture(QPixmap(QString(":/img/all.PNG")), GL_TEXTURE_2D);
    texture[2] = bindTexture(QPixmap(QString(":/img/vader.png")), GL_TEXTURE_2D);

    glEnable(GL_TEXTURE_2D);
    glColor4f(1.0f,1.0f,1.0f,1.0f);
    glEnable(GL_BLEND);
    glEnable(GL_ALPHA_TEST);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glAlphaFunc(GL_GREATER,0.1f);

}

// GL lango dydžio keitimo metodas,
// w - naujas lango plotis,
// h - naujas lango aukštis,
void GLWidget::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,w,0,h,-100,100);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0.0f,0.0f,0.0f,1.0f);
}

// GL kadro piešimo metodas
void GLWidget::paintGL()
{    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glColor3f(1.0f, 1.0f, 1.0f );
    glBindTexture(GL_TEXTURE_2D,texture[0]);
    glBegin(GL_QUADS);  // fonas
        glTexCoord2f(0.0f,0.0f); glVertex3i(  0, 0,-100);
        glTexCoord2f(0.0f,1.0f); glVertex3i(  0, 600,-100);
        glTexCoord2f(1.0f,1.0f); glVertex3i(800, 600,-100);
        glTexCoord2f(1.0f,0.0f); glVertex3i(800, 0,-100);
    glEnd();

    glLoadIdentity();


    static float pulse = 0.0f;
    pulse += 0.1f;
    float in = 0.5f; //0.75f + sin( pulse )/8.0f;

    if ( gameState == 0 ) { // Pagrindinis meniu

        glColor3f(1.0f, 1.0f, 1.0f );
        foreach ( TMLabel l, txt[0] ) {
            renderText( l.x, l.y, l.text, font );
        }
        foreach ( TMLabel l, myg[0] ) {
            if ( stateSelection[0] == l.action ) glColor3f(in, in, in ); else glColor3f(1.0f, 1.0f, 1.0f );
            renderText( l.x, l.y, l.text, font );
        }

    } else if ( gameState == 1 ) {  // Naujas žaidimas
        glColor3f(1.0f, 1.0f, 1.0f );
        foreach ( TMLabel l, txt[1] )
            renderText( l.x, l.y, l.text, font );
        renderText( txt[1][1].x2 + 40, 100, gameTypeStrings[gameType], font );
        renderText( txt[1][2].x2 + 40, 150, gamePlayersStrings[gamePlayers], font );
        foreach ( TMLabel l, myg[1] ) {
            if ( stateSelection[1] == l.action ) glColor3f(in, in, in ); else glColor3f(1.0f, 1.0f, 1.0f );
            renderText( l.x, l.y, l.text, font );
        }
    } else if ( gameState == 2 || gameState == 4 ) {  // Žaidimo stadija arba žaidimo pauzė
        glColor3f(1.0f, 1.0f, 1.0f );
        renderText( 10, 50, QString::fromStdWString(L"Žaidimo stadija"), font );

        static int pX = 50, pY = 60, sX = 10, sY = 10;
        if ( gameState == 2 ) { // valdymas ir fizika, šeip reiktų tai iškelti bet nenorių daryti globaliųjų kintamūjų
            pX += sX; pY += sY;
            if ( Ml.contains(Qt::LeftButton) ) {
                pX = Mx; pY = height()-My;
            }
            if ( pX < 0 ) sX = -sX; if ( pY < 0 ) sY = -sY;
            if ( pX > width() ) sX = -sX; if ( pY > height() ) sY = -sY;
        }

        glDisable(GL_TEXTURE_2D);   // kubikas
        glColor3f(1.0f, 0.8f, 0.8f );
        glBegin(GL_QUADS);  // fonas
            glVertex3i(  pX, pY,-100);
            glVertex3i(  pX, pY+10,-100);
            glVertex3i( pX+10, pY+10,-100);
            glVertex3i(pX+10, pY,-100);
        glEnd();
        glEnable(GL_TEXTURE_2D);

        if ( gameState == 4 ) { // žaidimo pauzė
            glDisable(GL_TEXTURE_2D);       // piešiamas pusiau permatomas juodas ekranas
            glColor4f(0.0f, 0.0f, 0.0f, 0.5f );
            glBegin(GL_QUADS);  // fonas
                glVertex3i(  0, 0,-100);
                glVertex3i(  0, 600,-100);
                glVertex3i(800, 600,-100);
                glVertex3i(800, 0,-100);
            glEnd();            
            glEnable(GL_TEXTURE_2D);
            
            glColor3f(1.0f, 1.0f, 1.0f );
            foreach ( TMLabel l, txt[2] ) { // tekstukai
                renderText( l.x, l.y, l.text, font );
            }
            foreach ( TMLabel l, myg[2] ) { // mygtukai
                if ( stateSelection[2] == l.action ) glColor3f(in, in, in ); else glColor3f(1.0f, 1.0f, 1.0f );
                renderText( l.x, l.y, l.text, font );
            }

        }
    } else {
        glColor3f(1.0f, 1.0f, 1.0f );
        this->renderText( 10, 50, QString::fromStdWString(L"Nežinomas game state: ") + QString::number(gameState), font );
    }

}

// metodas pagrindinei žaidimo logikai apdoroti
// return - grąžina 0 sekmingo vykdymo metu, -1 programos baigiui
int GLWidget::doLogic()
{
    if ( gameState == -1 ) {
        return -1;

    } else if ( gameState == 0 || gameState == 1 ) {    // main meniu arba naujas žaidimas
        int action = -1;

        if ( Kl.contains(Qt::Key_Return) )    // Enter
            action = stateSelection[gameState];  

        if ( Ml.contains(Qt::LeftButton) )    // pelės paspaudimas
            foreach ( TMLabel l, myg[gameState] )
                if ( l.x < Mx && Mx < l.x2 && l.y2+10 < My && My < l.y+10 )
                    action = l.action;

        if ( Mdx != 0 || Mdy != 0 )           // pelės žymėjimas
            foreach ( TMLabel l, myg[gameState] )
                if ( l.x < Mx && Mx < l.x2 && l.y2+10 < My && My < l.y+10 )
                    stateSelection[gameState] = l.action;

        if( Kl.contains(Qt::Key_Down) && stateSelection[gameState] < myg[gameState].size()-1 ) {  //  žymėjimas klaviatūra
            stateSelection[gameState]++;
        } else if( Kl.contains(Qt::Key_Up) && stateSelection[gameState] > 0 ) {
            stateSelection[gameState]--;
        }

        if ( gameState == 0 ) { // pagrindinis meniu
            if ( Kl.contains(Qt::Key_Escape) )
                action = 3; // Baigti žaidimą
            if ( action == 0 ) {    // Naujas žaidimas
                gameState = 1;
            } else if ( action == 1 ) { // Tęsti žaidimą
                QMessageBox::information( 0, QString::fromStdWString(L"Klaida"),
                                          QString::fromStdWString(L"Žaidimo tesimo funkcija dar nėra sukurta") );
            } else if ( action == 2 ) { // Nustatymai
                QMessageBox::information( 0, QString::fromStdWString(L"Klaida"),
                                          QString::fromStdWString(L"Nustatymų stadija dar nėra sukurta") );
            } else if ( action == 3 ) { // Baigti
                gameState = -1;
            }
        } else if ( gameState == 1 ) {  // naujas žaidimas
            if ( Kl.contains(Qt::Key_Escape) )
                action = 5; // grįžti į pagrindinį meniu
            if ( action == 0 ) {    // "<" žaidimo tipas
                if ( gameType > 0 )
                    gameType--;
            } else if ( action == 1 ) { // ">" žaidimo tipas
                if ( gameType < 1 )
                    gameType++;
            } else if ( action == 2 ) { // "<" žaidėjų tipas
                if ( gamePlayers > 0 )
                    gamePlayers--;
            } else if ( action == 3 ) { // ">" žaidėjų tipas
                if ( gamePlayers < 1 )
                    gamePlayers++;
            } else if ( action == 4 ) { // pradėti žaidimą
                gameState = 2;
            } else if ( action == 5 ) { // Grįžti
                gameState = 0;
            }
        }
    } else if ( gameState == 2 ) {  // pargindinė žaidimo stadija
        if  ( Kl.contains(Qt::Key_Escape) )
            gameState = 4;  // žaidimo pauzė

    } else if ( gameState == 4 ) {  // žaidimo pauzė
        int action = -1;

        if  ( Kl.contains(Qt::Key_Escape) )
            action = 4;  // grąžina į žaidimą
        if ( Kl.contains(Qt::Key_Return) )    // Enter
            action = stateSelection[2];

        if ( Ml.contains(Qt::LeftButton) )    // pelės paspaudimas
            foreach ( TMLabel l, myg[2] )
                if ( l.x < Mx && Mx < l.x2 && l.y2+10 < My && My < l.y+10 )
                    action = l.action;

        if ( Mdx != 0 || Mdy != 0 )           // pelės žymėjimas
            foreach ( TMLabel l, myg[2] )
                if ( l.x < Mx && Mx < l.x2 && l.y2+10 < My && My < l.y+10 )
                    stateSelection[2] = l.action;

        if( Kl.contains(Qt::Key_Down) && stateSelection[2] < myg[2].size()-1 ) {  //  žymėjimas klaviatūra
            stateSelection[2]++;
        } else if( Kl.contains(Qt::Key_Up) && stateSelection[2] > 0 ) {
            stateSelection[2]--;
        }

        if ( action == 0 ) {    // Nustatymai
            QMessageBox::information( 0, QString::fromStdWString(L"Klaida"),
                                      QString::fromStdWString(L"Nusatymų stadija dar nėra sukurta") );
        } else if ( action == 1 ) { // Išsaugoti žaidimą
            QMessageBox::information( 0, QString::fromStdWString(L"Klaida"),
                                      QString::fromStdWString(L"Žaidimo saugojimo funkcija dar nėra sukurta") );
        } else if ( action == 2 ) { // Pagalba
            QMessageBox::information( 0, QString::fromStdWString(L"Klaida"),
                                      QString::fromStdWString(L"Pagalbos stadija dar nėra sukurta") );
        } else if ( action == 3 ) { // Baigti žaidimą
            gameState = 0;
        } else if ( action == 4 ) { // Grįžti į žaidimą
            gameState = 2;
        }

    } else {
        if  ( Kl.contains(Qt::Key_Escape) )
            gameState = 0;  // grąžina į pagrindinį meniu
    }

    return 0;
}

// metodas priima mygtukų paspaudimo komandas ir jas sukelia į sąrašus
// e - QKeyEventas, informacija apie paspaustą/atspaustą mygtuką
// isPressed - ar mygtukas paspaustas
void GLWidget::handleKeys(QKeyEvent* e, bool isPressed)
{
    // mygtukų būsenos surašomos į hash lentelę
    if ( Kh.contains(e->key()) ) {   // hash table
        Kh[e->key()] = isPressed;
    } else {
        Kh.insert( e->key(), isPressed );
    }

    // visi paspausti mygtukai renkami į eilę, kad būtu apdoroti sekančio kadro metu
    if ( isPressed )
        Kq.enqueue( e->key() );
}

void GLWidget::mousePressEvent(QMouseEvent* e)
{
    Mh[e->button()] = true;
    Mq.enqueue( e->button() );
}

void GLWidget::mouseMoveEvent(QMouseEvent* e)
{
    move = true;
}

void GLWidget::mouseReleaseEvent(QMouseEvent* e)
{
    Mh[e->button()] = false;
}

// metodas tikrina pelės judėjimą, bei paruošia nuspaustų mygtukų eilę
void GLWidget::handleControls()
{
    static QPoint pos(QCursor::pos());
    static QPoint d;
    d = QCursor::pos() - pos;
    if ( mouseLocked )
        QCursor::setPos(500,400);   // "center" of the screen
    pos = QCursor::pos();
    Mdx = d.x();
    Mdy = d.y();

    QPoint p = this->mapFromGlobal(QCursor::pos());
    Mx = p.x();
    My = p.y();

    Ml.clear();
    while(!Mq.isEmpty())
        Ml.append(Mq.dequeue());

    Kl.clear();
    while (!Kq.isEmpty())
        Kl.append(Kq.dequeue());
}

// Metodas "užrakiną" pelę kad jos judėjimą gautu tik GL langas
void GLWidget::lockMouse()
{
    static QBitmap cur(16,16);
    cur.clear();
    QCursor::setPos(500,400);
    mouseLocked = true;
    this->grabMouse( QCursor(cur, cur, 0, 0) );
}

// metodas "atrakina" pelę
void GLWidget::unlockMouse()
{
    mouseLocked = false;
    this->releaseMouse();
}
